Skip to content

docs: bump the minimum Kotlin version + adopt purchases-android v11 - #1876

Merged
AlvaroBrey merged 6 commits into
11.0.0-devfrom
docs/kotlin-build-requirement
Sep 24, 2026
Merged

AlvaroBrey merged 6 commits into
11.0.0-devfrom
docs/kotlin-build-requirement

Conversation

@AlvaroBrey

@AlvaroBrey AlvaroBrey commented Aug 27, 2026 •

Copy link
Copy Markdown
Member

Targets the 11.0.0-dev major prep branch

Docs only. Adds the minimum Kotlin version that arrives with the next purchases-hybrid-common major.

  • purchases-android v11 publishes kotlin-stdlib 2.2.21 at compile scope, so its metadata is 2.2.0. A Kotlin compiler reads metadata at most one minor ahead, so an app on a compiler older than 2.1 fails to build.
  • Flutter applies the version declared in the app's android/settings.gradle to plugin subprojects, so the requirement lands on the consuming app. Verified: app at 1.8.22 fails, app at 2.1.21 builds, with the plugin's own ext.kotlin_version unchanged in both.
  • Flutter's own app template already ships Kotlin 2.3.20, so only existing projects need the bump.

Checklist

  • If applicable, unit tests were added
  • If applicable, followup issues for other SDKs were created

Note

Medium Risk
Raises minimum Kotlin and compileSdk for plugin and sample apps; temporary snapshot dependencies and extra Maven repos must be removed before release to avoid shipping unstable artifacts.

Overview
Documents Kotlin 2.1.0+ as a minimum Android requirement in the README, matching purchases-android v11’s Kotlin 2.2 metadata.

Sample and test Android projects (MaestroTestApp, purchase_tester) bump the Kotlin Android Gradle plugin from 1.8.22 to 2.2.21. purchases_ui_flutter moves its Kotlin toolchain to 2.2.21, raises compileSdk to 35, and temporarily pins purchases / purchases-ui at 11.0.0-SNAPSHOT so the module builds against v11.

Several app build.gradle files add a Sonatype snapshots Maven repo (scoped to com.revenuecat.purchases) with TODOs to drop those repos and snapshot pins before merge.

Reviewed by Cursor Bugbot for commit d449e77. Bugbot is set up for automated code reviews on this repo. Configure here.

@AlvaroBrey AlvaroBrey self-assigned this Aug 27, 2026
@AlvaroBrey AlvaroBrey changed the title docs: state the Kotlin build requirement on Android docs: state the minimum Kotlin version Aug 27, 2026
@AlvaroBrey
AlvaroBrey force-pushed the docs/kotlin-build-requirement branch from 99b7887 to 3f0c12f Compare August 27, 2026 09:25
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Aug 27, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

### Motivation

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

### Why not Kotlin 2.3.x

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

### Why AGP 9.2.1 and Gradle 9.4.1

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

### Also in this PR

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

### Deferred on purpose

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

### Testing

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

### Downstream

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>





<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
> 
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
> 
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
> 
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
> 
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
> 
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Aug 28, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

### Motivation

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

### Why not Kotlin 2.3.x

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

### Why AGP 9.2.1 and Gradle 9.4.1

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

### Also in this PR

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

### Deferred on purpose

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

### Testing

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

### Downstream

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>





<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
> 
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
> 
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
> 
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
> 
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
> 
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Aug 31, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

### Motivation

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

### Why not Kotlin 2.3.x

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

### Why AGP 9.2.1 and Gradle 9.4.1

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

### Also in this PR

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

### Deferred on purpose

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

### Testing

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

### Downstream

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>





<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
> 
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
> 
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
> 
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
> 
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
> 
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@AlvaroBrey
AlvaroBrey force-pushed the docs/kotlin-build-requirement branch from 3f0c12f to 8c97408 Compare August 31, 2026 14:11
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Sep 7, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
>
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
>
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
>
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
>
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
>
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Sep 7, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
>
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
>
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
>
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
>
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
>
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit to RevenueCat/purchases-android that referenced this pull request Sep 17, 2026
> [!NOTE]
> This targets branch `11.0-dev` which will become the epic branch for
the upcoming major release. Once this first PR is merged, I'll open a
continuous one from that one to `main` until we are ready to release it
altogether.

- Moves the SDK's build toolchain to AGP 9:

| Dependency | From | To |
|---|---|---|
| AGP | 8.13.2 | **9.2.1** |
| Gradle | 8.14.5 | **9.4.1** |
| Kotlin | 2.0.21 | **2.2.21** |
| Poko | 0.17.2 | **0.20.2** |
| Paparazzi | 2.0.0-alpha02 | **2.0.0-alpha05** |

- No public API change and no `api*.txt` diff.
- **Why this becomes a major**: this transitively raises the miminum
kotlin version for consumers to 2.1.0. up from 1.8.0.
- Kotlin lands on **2.2.21, the minimum required by AGP 9**,
- AGP is capped at **9.2.1** rather than latest: AGP 9.3.x requires
Gradle 9.5+, and Gradle 9.5+ embeds a Kotlin that a 2.2 compiler cannot
read, bumping consumers to an even higher minimum Kotlin version.
- Nothing downstream needs AGP 9 or Gradle 9, just the Kotlin bump. The
published AAR metadata is unchanged (`minCompileSdk=1`,
`minAndroidGradlePluginVersion=1.0.0`).

Companion docs PR: RevenueCat/docs#1942
Companion PHC PR:
RevenueCat/purchases-hybrid-common#1844

- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids

<details><summary>Agent description</summary>

AGP 8 is increasingly behind, and AGP 9 removes a number of DSL surfaces
we still used. The
prerequisite work already landed separately in #3931, #3961 and #3963.

AGP 9 has a runtime dependency on Kotlin Gradle Plugin **2.2.10 or
higher**, so a Kotlin bump is not
optional here. Everything above that floor is a choice, and this PR
deliberately takes the minimum.

An earlier revision of this branch used Kotlin 2.3.21. Measuring the
cost changed the decision:

- **It breaks every React Native consumer.** We publish `kotlin-stdlib`
at `compile` scope and Gradle
resolves consumers onto it. A compiler reads metadata at most one minor
ahead. Kotlin 2.3.x
publishes metadata 2.3.0, and React Native's own Gradle plugin pins the
compiler: 2.0.21 through
RN 0.79, 2.1.20 through RN 0.86, with only RN `main` on 2.2.0.
Reproduced on a real RN 0.86 app:
`metadata version is 2.3.0 / compiler version 2.1.0 can read versions up
to 2.2.0`. Every RN app
would have needed an explicit `kotlin-gradle-plugin` version in
`android/build.gradle`.
- **It forces the K2 migration.** Kotlin 2.3.21 rejects `languageVersion
1.8` outright. 2.2.x still
accepts it, so the frontend migration stays out of a version bump where
it does not belong.
- **It does not avoid a second bump anyway.** Kotlin 2.4 removes
`languageVersion 1.8` regardless.

At Kotlin 2.2.21 the published metadata is 2.2.0, which RN 0.81+ reads
untouched.

This is the non-obvious constraint, and CI found it rather than local
builds.

`:codegen` is a `java-gradle-plugin` module, so it compiles against the
Kotlin that **Gradle itself
embeds**. Embedded Kotlin by Gradle release:

| Gradle | Embedded Kotlin | Readable by a 2.2 compiler (max 2.3.0) |
|---|---|---|
| 9.3.1 | 2.2.21 | yes |
| 9.4.1 | 2.3.0 | yes, exactly at the limit |
| 9.5.1 | 2.3.20 | no |
| 9.7.0 | 2.4.0 | no |

Gradle 9.7.0 therefore failed `prepare-tests` with
`metadata version is 2.4.0, but the compiler version 2.2.0 can read
versions up to 2.3.0`.

AGP 9.3.x requires Gradle 9.5.0 or higher (`Minimum supported Gradle
version is 9.5.0`), which is
exactly the range we cannot read. **AGP 9.2.1 is the newest release that
runs on Gradle 9.4.1**;
9.1.1 and 9.0.1 were also confirmed to work, 9.3.1 was confirmed not to.

So the AGP ceiling here is a consequence of the Kotlin floor, not an
independent preference. When the
deferred Kotlin 2.3 bump happens, AGP and Gradle can move up with it.

- Standalone sample apps (`CustomEntitlementComputationSample`,
`MagicWeather`, `MagicWeatherCompose`)
move to Kotlin 2.2.21 and gain the `compose-compiler` plugin alias. They
consume our published
  artifacts, so they need a compiler that can read our metadata.
- Unit tests are re-enabled on the release variant via
`HasUnitTestBuilder.enableUnitTest`, because
AGP 9 only creates unit tests for the `testBuildType` variant and the
published variant is release.
- The `androidDependencies` cache-warm CI step is dropped; AGP 9 removed
that task.
- `migrations/v11-MIGRATION.md` documents the new Kotlin floor,
mirroring the v9 guide.
- README `Requirements` now says Kotlin 2.1.0+.

- **Kotlin 2.3 and the K1 to K2 migration**, until React Native ships
the KGP 2.2 pin already on its
`main` branch. Doing it sooner buys nothing and costs every RN app a
migration step.
- **AGP 9 built-in Kotlin** (previously #3965). Not breaking and not
required; the
`android.builtInKotlin=false` / `android.newDsl=false` opt-out only has
to go at AGP 10.

- `assembleDebug` across all modules; release AARs for `:purchases` and
`:ui:revenuecatui`.
- `:purchases` unit tests, `:ui:debugview:verifyPaparazziDefaultsDebug`,
`detektAll`.
- `scripts/api-check.sh` with **zero** `api*.txt` diff.
- Published contract checked directly: POM carries
`kotlin-stdlib:2.2.21` at `compile` scope, the
release AAR still reports `minCompileSdk=1` and
`minAndroidGradlePluginVersion=1.0.0`, and our own
  classes carry metadata `mv = {1, 8, 0}`.
- Consumer floor measured against the real release AAR plus the stdlib
we publish: Kotlin 2.1.21
compiles; 2.0.21 and 1.9.24 fail. That is what the 2.1.0 claim in the
README rests on.

The Kotlin floor is what propagates, not AGP. Nothing downstream needs
AGP 9 or Gradle 9.

The only direct consumer is purchases-hybrid-common, which re-exposes us
at compile scope via
`api(libs.purchases)`. RevenueCat/purchases-hybrid-common#1844 raises
its Kotlin accordingly, and the
hybrid SDKs pick the floor up from there rather than from this repo.

Documentation follows separately:

- RevenueCat/docs#1942 adds the Kotlin minimum to the Android, Flutter
and React Native installation
pages, and adds the 9.x-to-10.x and 10.x-to-11.x migration guides the
site was missing.
- RevenueCat/purchases-flutter#1876 states the Kotlin minimum in that
repo's README. Flutter applies
the version from the app's `android/settings.gradle`, so the requirement
lands on the consuming app
  and the Flutter version itself does not move.
- RevenueCat/react-native-purchases#1925 raises the React Native floor
to 0.80.0, the first release
  whose Gradle plugin pins a Kotlin that can read our metadata.

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major toolchain and minimum Kotlin version changes affect all
consumers and CI, though public API and published AAR AGP/minSdk
metadata are intentionally unchanged.
>
> **Overview**
> This PR moves the SDK build to **AGP 9.2.1**, **Gradle 9.4.1**, and
**Kotlin 2.2.21**, and bumps related tooling (Poko, Paparazzi, baseline
profile plugin). **`gradle.properties`** opts out of AGP 9’s built-in
Kotlin and new DSL for now.
>
> The **consumer-facing change** is a higher Kotlin floor: README and
**`migrations/v11-MIGRATION.md`** document **Kotlin 2.1.0+** (up from
1.8.0), driven by published stdlib metadata—not a public API change.
>
> **Build-logic** re-enables unit tests on library variants under AGP 9
via **`enableUnitTest`**, and keeps **`aarMetadata.minCompileSdk = 1`**
so published AAR requirements don’t tighten.
>
> Compose sample apps switch to the **Kotlin Compose compiler plugin**
and drop **`composeOptions.kotlinCompilerExtensionVersion`**. Several
modules replace deprecated **`kotlinOptions`** with
**`kotlin.compilerOptions.jvmTarget`**.
>
> **CircleCI** drops the removed **`androidDependencies`** warmup and
uses Gradle cache restore on standalone sample builds instead.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1b6b4df. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@AlvaroBrey
AlvaroBrey changed the base branch from main to 11.0.0-dev September 18, 2026 17:32
@AlvaroBrey
AlvaroBrey force-pushed the docs/kotlin-build-requirement branch from 8c97408 to 1cbc1ab Compare September 21, 2026 08:11
AlvaroBrey added a commit to RevenueCat/purchases-hybrid-common that referenced this pull request Sep 23, 2026
> Targets the next major branch (20.0-dev)

- Bumps Kotlin from 2.0.21 to 2.2.20.
- Bumps `purchases-android` to `11.0.0-SNAPSHOT` which is published from
the `11.0-dev` branch.
- **Required by the purchases-android v11 major**
(RevenueCat/purchases-android#3964). v11 publishes `kotlin-stdlib` with
metadata 2.2.0, and a Kotlin compiler reads metadata at most one minor
ahead, so our 2.0.21 compiler cannot consume it.
- **Raises the Kotlin floor for anything that compiles Kotlin against
PHC to 2.1**, because we publish `kotlin-stdlib` at compile scope too.
This is not extra breakage: `api(libs.purchases)` re-exposes purchases
at compile scope, so the v11 bump forces the same floor regardless of
what PHC itself compiles with.
- `kotlinLanguage` deliberately stays at `1.8`. Kotlin 2.2.20 still
accepts it, so this is a compiler bump and not a K1 to K2 migration.

Companion PRs: RevenueCat/purchases-flutter#1876
RevenueCat/react-native-purchases#1925

### Checklist
- [x] A description about what and why you are contributing
- [x] The issue number(s) or PR number(s) in the description
- [ ] If applicable, unit tests

<details><summary>Agent description</summary>

### Motivation

purchases-android v11 moves to Kotlin 2.2.21 as part of its AGP 9
upgrade. The Kotlin Gradle Plugin
publishes `kotlin-stdlib` at `compile` scope, so Gradle resolves
consumers onto it, and a compiler
can only read metadata from at most one minor version ahead of itself.
v11's stdlib carries metadata
2.2.0, which a 2.0.21 compiler rejects with:

```
Module was compiled with an incompatible version of Kotlin.
The binary version of its metadata is 2.2.0, expected version is 2.0.0.
```

So PHC has to move to at least 2.1 before it can take v11. 2.2.20 is
chosen to match what
purchases-capacitor already pins, so the hybrids converge on one
version.

### Why this is separable from the purchases bump

PHC compiles cleanly on Kotlin 2.2.20 with `purchases` still at 10.18.1,
verified locally. That makes
this landable before the v11 release rather than gated behind it, which
is the whole reason it is its
own PR.

### Downstream impact

Consumers that compile Kotlin against PHC need a compiler of 2.1 or
newer after this:

| Consumer | Compiler | Status |
|---|---|---|
| purchases-flutter `purchases_ui_flutter` | KGP 1.9.20 | needs
RevenueCat/purchases-flutter#1875 |
| react-native apps on RN 0.78 / 0.79 | KGP 2.0.21 | needs
RevenueCat/react-native-purchases#1925 |
| react-native apps on RN 0.81+ | KGP 2.1.20 | fine, reads 2.2.0 |
| purchases-capacitor | 2.2.20 | fine |
| cordova, unity | Java only, no Kotlin compilation | fine |

**Merging this is safe. Releasing it is what needs sequencing.** Once a
PHC version ships with this,
the automated PHC bump PRs open against purchases-flutter and
react-native-purchases and will fail
their CI until their Kotlin prep lands. Land #1875 and #1925 first, or
hold the PHC release for the
coordinated major.

### Testing

`cd android && ./gradlew assembleRelease` passes on 2.2.20 with
`purchases` unchanged at 10.18.1.
Only pre-existing deprecation warnings, plus the expected `Language
version 1.8 is deprecated` note.
The generated POM confirms the new contract: `kotlin-stdlib:2.2.20` at
`compile` scope.

### Related

- RevenueCat/purchases-android#3964 introduces the floor this responds
to
- RevenueCat/purchases-flutter#1875 and
RevenueCat/react-native-purchases#1925 are the downstream
  Kotlin bumps that must land before a PHC release carrying this

</details>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major dependency and Kotlin compiler bumps affect all Android modules
and raise the minimum Kotlin version for consumers once released;
snapshot repo adds transient resolution risk until v11 is stable.
> 
> **Overview**
> **Aligns the Android hybrid-common build with purchases-android v11**
by bumping the Kotlin toolchain and core SDK dependency, plus raising
the compile SDK across modules.
> 
> The version catalog moves **Kotlin from 2.0.21 to 2.2.21** and
**`purchases-android` from 10.22.1 to `11.0.0-SNAPSHOT`** (with a note
to pin stable `11.0.0` later). **`compileSdk` is raised from 34 to 36**
in `api-tests`, `hybridcommon`, `hybridcommon-ui`, and
`hybridcommon-store-galaxy`.
> 
> **Gradle resolution** adds a temporary **Sonatype Maven Snapshots**
repository scoped to `com.revenuecat.purchases` so the v11 snapshot
resolves until it ships to Maven Central.
> 
> This is primarily a **compiler and dependency floor** change (Kotlin
metadata from v11 requires a newer compiler); `kotlinLanguage` stays at
1.8 per the PR intent.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a6c1eb3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
purchases-android v11 publishes kotlin-stdlib 2.2.21 at compile scope, so
its metadata is 2.2.0 and a compiler older than 2.1 cannot read it. Flutter
applies the app's own Kotlin Gradle Plugin version to plugin subprojects, so
the requirement lands on the consuming app.
purchases-android v11 publishes stdlib metadata 2.2.0. Kotlin 1.9.20 rejects it with
"The binary version of its metadata is 2.2.0, expected version is 1.9.0", so this module
could not compile against v11 at all.
Scaffolding to prove the Kotlin bump against real v11 artifacts before release.
Revert both the snapshot repository and the two pins before merging.
The apps compile their own MainActivity against purchases-android transitively, so a
1.8.22 compiler cannot read v11's metadata either.
@AlvaroBrey
AlvaroBrey force-pushed the docs/kotlin-build-requirement branch from 1cbc1ab to 526a647 Compare September 24, 2026 08:52
@AlvaroBrey AlvaroBrey changed the title docs: state the minimum Kotlin version docs: bump the minimum Kotlin version + adopt purchases-android v11 Sep 24, 2026
@AlvaroBrey
AlvaroBrey marked this pull request as ready for review September 24, 2026 08:54
@AlvaroBrey
AlvaroBrey requested a review from a team as a code owner September 24, 2026 08:54

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 526a647. Configure here.

Comment thread purchases_ui_flutter/android/build.gradle
Flutter builds the plugin as a subproject of the app, so the app's repositories decide
resolution, not the plugin's. Revert with the pins in purchases_ui_flutter.
@AlvaroBrey
AlvaroBrey force-pushed the docs/kotlin-build-requirement branch from 526a647 to e3a03b7 Compare September 24, 2026 09:01
@AlvaroBrey
AlvaroBrey requested a review from a team September 24, 2026 09:03

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there are still some tests failing, but in any case this PR looks good! we can tackle those failures in follow-ups

@AlvaroBrey

Copy link
Copy Markdown
Member Author

Looks like there are still some tests failing, but in any case this PR looks good! we can tackle those failures in follow-ups

fixed! raised compileSdk

@AlvaroBrey
AlvaroBrey merged commit e4dc893 into 11.0.0-dev Sep 24, 2026
21 checks passed
@AlvaroBrey
AlvaroBrey deleted the docs/kotlin-build-requirement branch September 24, 2026 09:26
AlvaroBrey added a commit to RevenueCat/purchases-hybrid-common that referenced this pull request Sep 24, 2026
> Targets the next major branch (20.0-dev)

- Bumps Kotlin from 2.0.21 to 2.2.20.
- Bumps `purchases-android` to `11.0.0-SNAPSHOT` which is published from
the `11.0-dev` branch.
- **Required by the purchases-android v11 major**
(RevenueCat/purchases-android#3964). v11 publishes `kotlin-stdlib` with
metadata 2.2.0, and a Kotlin compiler reads metadata at most one minor
ahead, so our 2.0.21 compiler cannot consume it.
- **Raises the Kotlin floor for anything that compiles Kotlin against
PHC to 2.1**, because we publish `kotlin-stdlib` at compile scope too.
This is not extra breakage: `api(libs.purchases)` re-exposes purchases
at compile scope, so the v11 bump forces the same floor regardless of
what PHC itself compiles with.
- `kotlinLanguage` deliberately stays at `1.8`. Kotlin 2.2.20 still
accepts it, so this is a compiler bump and not a K1 to K2 migration.

Companion PRs: RevenueCat/purchases-flutter#1876
RevenueCat/react-native-purchases#1925

- [x] A description about what and why you are contributing
- [x] The issue number(s) or PR number(s) in the description
- [ ] If applicable, unit tests

<details><summary>Agent description</summary>

purchases-android v11 moves to Kotlin 2.2.21 as part of its AGP 9
upgrade. The Kotlin Gradle Plugin
publishes `kotlin-stdlib` at `compile` scope, so Gradle resolves
consumers onto it, and a compiler
can only read metadata from at most one minor version ahead of itself.
v11's stdlib carries metadata
2.2.0, which a 2.0.21 compiler rejects with:

```
Module was compiled with an incompatible version of Kotlin.
The binary version of its metadata is 2.2.0, expected version is 2.0.0.
```

So PHC has to move to at least 2.1 before it can take v11. 2.2.20 is
chosen to match what
purchases-capacitor already pins, so the hybrids converge on one
version.

PHC compiles cleanly on Kotlin 2.2.20 with `purchases` still at 10.18.1,
verified locally. That makes
this landable before the v11 release rather than gated behind it, which
is the whole reason it is its
own PR.

Consumers that compile Kotlin against PHC need a compiler of 2.1 or
newer after this:

| Consumer | Compiler | Status |
|---|---|---|
| purchases-flutter `purchases_ui_flutter` | KGP 1.9.20 | needs
RevenueCat/purchases-flutter#1875 |
| react-native apps on RN 0.78 / 0.79 | KGP 2.0.21 | needs
RevenueCat/react-native-purchases#1925 |
| react-native apps on RN 0.81+ | KGP 2.1.20 | fine, reads 2.2.0 |
| purchases-capacitor | 2.2.20 | fine |
| cordova, unity | Java only, no Kotlin compilation | fine |

**Merging this is safe. Releasing it is what needs sequencing.** Once a
PHC version ships with this,
the automated PHC bump PRs open against purchases-flutter and
react-native-purchases and will fail
their CI until their Kotlin prep lands. Land #1875 and #1925 first, or
hold the PHC release for the
coordinated major.

`cd android && ./gradlew assembleRelease` passes on 2.2.20 with
`purchases` unchanged at 10.18.1.
Only pre-existing deprecation warnings, plus the expected `Language
version 1.8 is deprecated` note.
The generated POM confirms the new contract: `kotlin-stdlib:2.2.20` at
`compile` scope.

- RevenueCat/purchases-android#3964 introduces the floor this responds
to
- RevenueCat/purchases-flutter#1875 and
RevenueCat/react-native-purchases#1925 are the downstream
  Kotlin bumps that must land before a PHC release carrying this

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major dependency and Kotlin compiler bumps affect all Android modules
and raise the minimum Kotlin version for consumers once released;
snapshot repo adds transient resolution risk until v11 is stable.
>
> **Overview**
> **Aligns the Android hybrid-common build with purchases-android v11**
by bumping the Kotlin toolchain and core SDK dependency, plus raising
the compile SDK across modules.
>
> The version catalog moves **Kotlin from 2.0.21 to 2.2.21** and
**`purchases-android` from 10.22.1 to `11.0.0-SNAPSHOT`** (with a note
to pin stable `11.0.0` later). **`compileSdk` is raised from 34 to 36**
in `api-tests`, `hybridcommon`, `hybridcommon-ui`, and
`hybridcommon-store-galaxy`.
>
> **Gradle resolution** adds a temporary **Sonatype Maven Snapshots**
repository scoped to `com.revenuecat.purchases` so the v11 snapshot
resolves until it ships to Maven Central.
>
> This is primarily a **compiler and dependency floor** change (Kotlin
metadata from v11 requires a newer compiler); `kotlinLanguage` stays at
1.8 per the PR intent.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a6c1eb3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit that referenced this pull request Sep 28, 2026
…1876)

> Targets the `11.0.0-dev` major prep branch

Docs only. Adds the minimum Kotlin version that arrives with the next
purchases-hybrid-common major.

- purchases-android v11 publishes `kotlin-stdlib` 2.2.21 at compile
scope, so its metadata is 2.2.0. A Kotlin compiler reads metadata at
most one minor ahead, so an app on a compiler older than 2.1 fails to
build.
- Flutter applies the version declared in the **app's**
`android/settings.gradle` to plugin subprojects, so the requirement
lands on the consuming app. Verified: app at 1.8.22 fails, app at 2.1.21
builds, with the plugin's own `ext.kotlin_version` unchanged in both.
- Flutter's own app template already ships Kotlin 2.3.20, so only
existing projects need the bump.

- [ ] If applicable, unit tests were added
- [ ] If applicable, followup issues for other SDKs were created

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Raises minimum Kotlin and compileSdk for plugin and sample apps;
temporary snapshot dependencies and extra Maven repos must be removed
before release to avoid shipping unstable artifacts.
>
> **Overview**
> Documents **Kotlin 2.1.0+** as a minimum Android requirement in the
README, matching purchases-android v11’s Kotlin 2.2 metadata.
>
> Sample and test Android projects (**MaestroTestApp**,
**purchase_tester**) bump the Kotlin Android Gradle plugin from
**1.8.22** to **2.2.21**. **`purchases_ui_flutter`** moves its Kotlin
toolchain to **2.2.21**, raises **compileSdk** to **35**, and
temporarily pins **`purchases`** / **`purchases-ui`** at
**11.0.0-SNAPSHOT** so the module builds against v11.
>
> Several app **`build.gradle`** files add a Sonatype snapshots Maven
repo (scoped to `com.revenuecat.purchases`) with TODOs to drop those
repos and snapshot pins before merge.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d449e77. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
AlvaroBrey added a commit to RevenueCat/purchases-hybrid-common that referenced this pull request Sep 28, 2026
> Targets the next major branch (20.0-dev)

- Bumps Kotlin from 2.0.21 to 2.2.20.
- Bumps `purchases-android` to `11.0.0-SNAPSHOT` which is published from
the `11.0-dev` branch.
- **Required by the purchases-android v11 major**
(RevenueCat/purchases-android#3964). v11 publishes `kotlin-stdlib` with
metadata 2.2.0, and a Kotlin compiler reads metadata at most one minor
ahead, so our 2.0.21 compiler cannot consume it.
- **Raises the Kotlin floor for anything that compiles Kotlin against
PHC to 2.1**, because we publish `kotlin-stdlib` at compile scope too.
This is not extra breakage: `api(libs.purchases)` re-exposes purchases
at compile scope, so the v11 bump forces the same floor regardless of
what PHC itself compiles with.
- `kotlinLanguage` deliberately stays at `1.8`. Kotlin 2.2.20 still
accepts it, so this is a compiler bump and not a K1 to K2 migration.

Companion PRs: RevenueCat/purchases-flutter#1876
RevenueCat/react-native-purchases#1925

- [x] A description about what and why you are contributing
- [x] The issue number(s) or PR number(s) in the description
- [ ] If applicable, unit tests

<details><summary>Agent description</summary>

purchases-android v11 moves to Kotlin 2.2.21 as part of its AGP 9
upgrade. The Kotlin Gradle Plugin
publishes `kotlin-stdlib` at `compile` scope, so Gradle resolves
consumers onto it, and a compiler
can only read metadata from at most one minor version ahead of itself.
v11's stdlib carries metadata
2.2.0, which a 2.0.21 compiler rejects with:

```
Module was compiled with an incompatible version of Kotlin.
The binary version of its metadata is 2.2.0, expected version is 2.0.0.
```

So PHC has to move to at least 2.1 before it can take v11. 2.2.20 is
chosen to match what
purchases-capacitor already pins, so the hybrids converge on one
version.

PHC compiles cleanly on Kotlin 2.2.20 with `purchases` still at 10.18.1,
verified locally. That makes
this landable before the v11 release rather than gated behind it, which
is the whole reason it is its
own PR.

Consumers that compile Kotlin against PHC need a compiler of 2.1 or
newer after this:

| Consumer | Compiler | Status |
|---|---|---|
| purchases-flutter `purchases_ui_flutter` | KGP 1.9.20 | needs
RevenueCat/purchases-flutter#1875 |
| react-native apps on RN 0.78 / 0.79 | KGP 2.0.21 | needs
RevenueCat/react-native-purchases#1925 |
| react-native apps on RN 0.81+ | KGP 2.1.20 | fine, reads 2.2.0 |
| purchases-capacitor | 2.2.20 | fine |
| cordova, unity | Java only, no Kotlin compilation | fine |

**Merging this is safe. Releasing it is what needs sequencing.** Once a
PHC version ships with this,
the automated PHC bump PRs open against purchases-flutter and
react-native-purchases and will fail
their CI until their Kotlin prep lands. Land #1875 and #1925 first, or
hold the PHC release for the
coordinated major.

`cd android && ./gradlew assembleRelease` passes on 2.2.20 with
`purchases` unchanged at 10.18.1.
Only pre-existing deprecation warnings, plus the expected `Language
version 1.8 is deprecated` note.
The generated POM confirms the new contract: `kotlin-stdlib:2.2.20` at
`compile` scope.

- RevenueCat/purchases-android#3964 introduces the floor this responds
to
- RevenueCat/purchases-flutter#1875 and
RevenueCat/react-native-purchases#1925 are the downstream
  Kotlin bumps that must land before a PHC release carrying this

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Major dependency and Kotlin compiler bumps affect all Android modules
and raise the minimum Kotlin version for consumers once released;
snapshot repo adds transient resolution risk until v11 is stable.
>
> **Overview**
> **Aligns the Android hybrid-common build with purchases-android v11**
by bumping the Kotlin toolchain and core SDK dependency, plus raising
the compile SDK across modules.
>
> The version catalog moves **Kotlin from 2.0.21 to 2.2.21** and
**`purchases-android` from 10.22.1 to `11.0.0-SNAPSHOT`** (with a note
to pin stable `11.0.0` later). **`compileSdk` is raised from 34 to 36**
in `api-tests`, `hybridcommon`, `hybridcommon-ui`, and
`hybridcommon-store-galaxy`.
>
> **Gradle resolution** adds a temporary **Sonatype Maven Snapshots**
repository scoped to `com.revenuecat.purchases` so the v11 snapshot
resolves until it ships to Maven Central.
>
> This is primarily a **compiler and dependency floor** change (Kotlin
metadata from v11 requires a newer compiler); `kotlinLanguage` stays at
1.8 per the PR intent.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a6c1eb3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants